package com.xiaobo.framework.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static com.xiaobo.framework.bean.MqInfo.slaveOneQueue;
import static com.xiaobo.framework.bean.MqInfo.slaveTwoQueue;
import static com.xiaobo.framework.bean.MqInfo.directExchange;
import static com.xiaobo.framework.bean.MqInfo.topicExchange;
import static com.xiaobo.framework.bean.MqInfo.fanoutExchange;

/**
 * @author: <a href="get_xiaobo@163.com">Josh_Xu</a>
 * @description:
 * @create: 2020-05-18 13:51
 **/
@Slf4j
@Configuration
public class MqConfig {

    @Bean
    public Queue slaveOneQueue() {
        return new Queue(slaveOneQueue);
    }

    @Bean
    public Queue slaveTwoQueue() {
        return new Queue(slaveTwoQueue);
    }

    @Bean
    public Queue message() {
        return new Queue("topic.message");
    }

    @Bean
    public Queue messages() {
        return new Queue("topic.messages");
    }

    /**
     * **
     *  exchange是交换机交换机的主要作用是接收相应的消息并且绑定到指定的队列.交换机有四种类型,分别为Direct,topic,headers,Fanout.
     *
     *  Direct是RabbitMQ默认的交换机模式,也是最简单的模式.即创建消息队列的时候,指定一个BindingKey.当发送者发送消息的时候,指定对应的Key.当Key和消息队列的BindingKey一致的时候,消息将会被发送到该消息队列中.
     *
     *  topic转发信息主要是依据通配符,队列和交换机的绑定主要是依据一种模式(通配符+字符串),而当发送消息的时候,只有指定的Key和该模式相匹配的时候,消息才会被发送到该消息队列中.
     *
     *  headers也是根据一个规则进行匹配,在消息队列和交换机绑定的时候会指定一组键值对规则,而发送消息的时候也会指定一组键值对规则,当两组键值对规则相匹配的时候,消息会被发送到匹配的消息队列中.
     *
     *  Fanout是路由广播的形式,将会把消息发给绑定它的全部队列,即便设置了key,也会被忽略.
     *  */

    /**
     * 路由交换机
     *
     * @return
     */
    @Bean
    DirectExchange directExchange() {
        return new DirectExchange(directExchange);
    }

    /**
     * 动态路由器交换机
     * 通配符
     *
     * @return
     */
    @Bean
    TopicExchange topicExchange() {
        return new TopicExchange(topicExchange);
    }

    /**
     * 广播路由器交换机
     *
     * @return FanoutExchange
     */
    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeDirect(@Qualifier("slaveOneQueue") Queue slaveOneQueue, DirectExchange directExchange) {
        return BindingBuilder
                .bind(slaveOneQueue)
                .to(directExchange)
                .with("direct");
    }

    /**
     * 将队列topic.messages与exchange绑定，routing_key为topic.#,模糊匹配
     *
     * @param messages
     * @param exchange
     * @return
     */
    @Bean
    Binding bindingExchangeMessages(@Qualifier("messages") Queue messages, TopicExchange exchange) {
        return BindingBuilder.bind(messages).to(exchange).with("topic.#");
    }

    /**
     * @param message
     * @param exchange
     * @return
     */
    @Bean
    Binding bindingExchangeMessage(@Qualifier("message") Queue message, TopicExchange exchange) {
        return BindingBuilder.bind(message).to(exchange).with("topic.message");
    }

}
